package com.restaurant.application.util.counter.support;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.nebutown.generation.Convert;
import com.nebutown.generation.PickableBean;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CounterData implements PickableBean {

    public static final String FN_DATA = "data";

    public static final List<String> FIELD_NAMES = Lists.newArrayList(
            FN_DATA);

    private Map<String, CounterValue> data;

    public CounterData(Map<String, CounterValue> data) {
        setData(data);
    }

    public CounterData() {
    }

    public CounterData duplicate() {
        CounterData result = new CounterData();
        result.data = this.data == null ? null : this.data.keySet().stream().collect(Collectors.toConcurrentMap(e1 -> e1, e1 -> this.data.get(e1) == null ? null : this.data.get(e1).duplicate()));
        return result;
    }

    @Override
    public String toString() {
        return Convert.toJson(this);
    }

    public Map<String, CounterValue> getData() {
        if (data == null) {
            data = Maps.newConcurrentMap();
        }
        return data;
    }

    public void setData(Map<String, CounterValue> value) {
        this.data = value;
    }

    public CounterData withData(Map<String, CounterValue> value) {
        setData(value);
        return this;
    }

    public CounterData withData(Map<String, CounterValue> value, Map<String, CounterValue> defaultValue) {
        setData(value == null ? defaultValue : value);
        return this;
    }

    public CounterData putData(String key, CounterValue value) {
        if (data == null) {
            data = Maps.newConcurrentMap();
        }
        this.data.put(key, value);
        return this;
    }

    public Object getValueOf(String name) {
        switch (name) {
            case "data":
                return getData();
        }
        return null;
    }

    public boolean hasField(String name) {
        return FIELD_NAMES.contains(name);
    }

    @Override
    public int hashCode() {
        return signature().hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof CounterData)) return false;
        return signature().equals(((CounterData) o).signature());
    }

    public String signature() {
        throw new RuntimeException("Bean CounterData has no signature defined, no hash code or equals possible.");
    }
}
